/*
    Heart of Gold engine management system
    Copyright (C) 2004 Heart of Gold development team

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*  A threaded implementation of the java to C
 * communications for the HeartOfGold
 *
 * @author Ryan T. Higgins
 * @date 29Mar04
 * @revision
 */

package com.heartOfGold.model.megasquirtECU;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import com.heartOfGold.model.Formatter;
import com.heartOfGold.model.Message;
import com.heartOfGold.model.ModelMessenger;
import com.heartOfGold.model.NMEA;



//import java.util.Observable;

public final class MegasquirtMessenger extends ModelMessenger {

    private static MegasquirtMessenger theMessenger = null;
    private PipeWatcher theWatcher;
    private DataOutputStream out;
    private Formatter parser;
    private Formatter parser2;
    private String writeTo;

    private class PipeWatcher extends Thread {
        private DataInputStream in;
        private int bufSize = 1024;
        private byte[] c = new byte[bufSize];
        private String pipeName;

        public PipeWatcher() {
        }

        public PipeWatcher(final String source) {
            pipeName = source;
            return;
        }

        public void connectSource(final String source) {
            pipeName = source;
            return;
        }

        public void getMessage(final byte[] bytes, final int numBytes)
                throws java.io.IOException {
            Message ms;
            MegasquirtMessenger m = MegasquirtMessenger.getMessenger();
            NMEA n = NMEA.getNMEA();
            Formatter mf = MegaFormatter.getMega();
            /*
             * if(numBytes > 5){ if((char)bytes[bytes.length - 5] == '*'){mf =
             * n;} }
             */
            mf = n;
            ms = mf.parseBytes(bytes, numBytes);
            if (ms != null) {
                m.setChanged();
                m.notifyObservers(ms); // Should we put out an error if null?
            }
            return;
        }

        public void run() {
            // need error checking to see if in is valid
            int numRead = 0;
            try {
                in = new DataInputStream(new FileInputStream(pipeName));
                for (;;) {
                    numRead = in.read(c, 0, bufSize);
                    if (numRead != 0) {
                        getMessage(c, numRead);
                    }
                }
            } catch (IOException e) {
            }
            return;
        }
    }

    public static MegasquirtMessenger getMessenger() throws java.io.IOException {
        if (theMessenger == null) {
            theMessenger = new MegasquirtMessenger();
        }
        return theMessenger;
    }

    public static MegasquirtMessenger getMessenger(final String inPipe,
            final String outPipe) throws java.io.IOException {
        if (theMessenger == null) {
            theMessenger = new MegasquirtMessenger(inPipe, outPipe);
        }
        return theMessenger;
    }

    private MegasquirtMessenger() throws java.io.IOException {
        theWatcher = new PipeWatcher();
        parser = NMEA.getNMEA();
        parser2 = MegaFormatter.getMega();
        return;
    }

    private MegasquirtMessenger(final String inPipe, final String outPipe)
            throws java.io.IOException {
        theWatcher = new PipeWatcher(inPipe);
        parser = NMEA.getNMEA();
        parser2 = MegaFormatter.getMega();
        out = null;
        writeTo = outPipe;
        return;
    }

    public void connectInput(final String inPipe) {
        theWatcher.connectSource(inPipe);
        return;
    }

    public void connectOutput(final String outPipe) {
        writeTo = new String(outPipe);
        return;
    }

    public void startMessaging() {
        theWatcher.start();
        return;
    }

    public void sendMessage(final Message message)
            throws java.io.IOException {
        out = new DataOutputStream(new FileOutputStream(writeTo));
        byte[] bytes;
        if ((message.getID()).equals("fuel")) {
            bytes = parser2.parseMessage(message);
        } else {
            bytes = parser.parseMessage(message);
        }
        if (bytes != null) {
            out.write(bytes, 0, bytes.length); // Send error if null?
        }
        out.close();
        return;
    }
}
